<!DOCTYPE html>
<html>
<head>
	<!-- Global site tag (gtag.js) - Google Analytics -->
	<script async src="https://www.googletagmanager.com/gtag/js?id='UA-133422980-2"></script>
	<script>
	  window.dataLayer = window.dataLayer || [];
	  function gtag(){dataLayer.push(arguments);}
	  gtag('js', new Date());

	  gtag('config', 'UA-133422980-2');
	</script>

	<meta charset="utf-8">
	<meta http-equiv="x-ua-compatible" content="ie=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1">

	<title>
		gem5: Configuring for a standard protocol 
	</title>

	<!-- SITE FAVICON -->
	<link rel="shortcut icon" type="image/gif" href="/assets/img/gem5ColorVert.gif"/>

	<link rel="canonical" href="http://localhost:4000/documentation/learning_gem5/part3/simple-MI_example/">
	<link href='https://fonts.googleapis.com/css?family=Open+Sans:400,300,700,800,600' rel='stylesheet' type='text/css'>
	<link href='https://fonts.googleapis.com/css?family=Muli:400,300' rel='stylesheet' type='text/css'>

	<!-- FAVICON -->
	<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">

	<!-- BOOTSTRAP -->
	<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">

	<!-- CUSTOM CSS -->
	<link rel="stylesheet" href="/css/main.css">
</head>


<body>
	<nav class="navbar navbar-expand-md navbar-light bg-light">
  <a class="navbar-brand" href="/">
		<img src="/assets/img/gem5ColorLong.gif" alt="gem5" height=55px>
	</a>
  <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavDropdown" aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
    <span class="navbar-toggler-icon"></span>
  </button>
  <div class="collapse navbar-collapse" id="navbarNavDropdown">
    <!-- LIST FOR NAVBAR -->
    <ul class="navbar-nav ml-auto">
      <!-- HOME -->
      <li class="nav-item ">
        <a class="nav-link" href="/">Home</a>
      </li>

      <!-- ABOUT -->
			<li class="nav-item dropdown ">
				<a class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
					About
				</a>
				<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
          <a class="dropdown-item" href="/about">About gem5</a>
          <a class="dropdown-item" href="/publications">Publications</a>
          <a class="dropdown-item" href="/governance">Governance</a>
				</div>
			</li>

      <!-- DOCUMENTATION -->
			<li class="nav-item dropdown active">
				<a class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
					Documentation
				</a>
				<div class="dropdown-menu" aria-labelledby="navbarDropdownMenuLink">
					<!-- Pull navigation from _data/documentation.yml -->
					
            <a class="dropdown-item" href="/documentation">gem5 documentation</a>
					
            <a class="dropdown-item" href="/documentation/learning_gem5/introduction">Learning gem5</a>
					
            <a class="dropdown-item" href="http://doxygen.gem5.org/release/current/index.html">gem5 Doxygen</a>
					
            <a class="dropdown-item" href="/documentation/reporting_problems">Reporting Problems</a>
					
				</div>
			</li>

      <!-- EVENTS -->
			<li class="nav-item dropdown ">
        <a class="nav-link" href="/events/">Events</a>
			</li>

      <!-- CONTRIBUTING -->
      <li class="nav-item ">
        <a class="nav-link" href="/contributing">Contributing</a>
      </li>

      <!-- BLOG -->
      <li class="nav-item ">
        <a class="nav-link" href="/blog">Blog</a>
      </li>

      <!-- SEARCH -->
			<li class="nav-item ">
        <a class="nav-link" href="/search">Search</a>
      </li>
    </ul>
  </div>
</nav>

	<main>
		<div class="sidenav-top">
  <div class="sidenav-brand bg-light">
    <a href="/"><img src="/assets/img/gem5ColorLong.gif" height="55px"></a>
  </div>
  <div class="search">
    <form action="/search" method="get">
      <!-- <label for="search-box"><i class="fa fa-search"></i></label> -->
      <input type="text" name="query">
      <button type="submit" name="submit"><i class="fa fa-search"></i></button>
    </form>
  </div>
</div>
<div class="sidenav">
  <!-- Pull navigation from _data/documentation.yml -->
  
    
  
    
    
      <a class="item" href="/documentation/learning_gem5/introduction" role="button" aria-expanded="false" aria-controls="collapseExample">
        Introduction
      </a>
      <div class="collapse " id="introduction">
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#part1" role="button" aria-expanded="false" aria-controls="collapseExample">
        Getting Started
      </a>
      <div class="collapse " id="part1">
        
          <a class="subitem " href="/documentation/learning_gem5/part1/building">Building gem5</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part1/simple_config">Creating a simple configuration script</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part1/cache_config">Adding cache to configuration script</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part1/gem5_stats">Understanding gem5 statistics and output</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part1/example_configs">Using the default configuration scripts</a>
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#part2" role="button" aria-expanded="false" aria-controls="collapseExample">
        Modifying/Extending
      </a>
      <div class="collapse " id="part2">
        
          <a class="subitem " href="/documentation/learning_gem5/part2/environment">Setting up your development environment</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/helloobject">Creating a very simple SimObject</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/debugging">Debugging gem5</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/events">Event-driven programming</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/parameters">Adding parameters to SimObjects and more events</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/memoryobject">Creating SimObjects in the memory system</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part2/simplecache">Creating a simple cache object</a>
        
      </div>
    
      <a class="item" data-toggle="collapse" href="#part3" role="button" aria-expanded="false" aria-controls="collapseExample">
        Modeling Cache Coherence with Ruby
      </a>
      <div class="collapse show" id="part3">
        
          <a class="subitem " href="/documentation/learning_gem5/part3/MSIintro">Introduction to Ruby</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/cache-intro">MSI example cache protocol</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/cache-declarations">Declaring a state machine</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/cache-in-ports">In port code blocks</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/cache-actions">Action code blocks</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/cache-transitions">Transition code blocks</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/directory">MSI Directory implementation</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/MSIbuilding">Compiling a SLICC protocol</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/configuration">Configuring a simple Ruby system</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/running">Running the simple Ruby system</a>
        
          <a class="subitem " href="/documentation/learning_gem5/part3/MSIdebugging">Debugging SLICC Protocols</a>
        
          <a class="subitem active" href="/documentation/learning_gem5/part3/simple-MI_example">Configuring for a standard protocol</a>
        
      </div>
    
      <a class="item" href="/documentation/learning_gem5/gem5_101/" role="button" aria-expanded="false" aria-controls="collapseExample">
        gem5 101
      </a>
      <div class="collapse " id="gem5_101">
        
      </div>
    
    
  
    
  
    
  
</div>


<div class="container" id="doc-container">
  <div class="edit"><a href="https://gem5.googlesource.com/public/gem5-website/+/refs/heads/master/README.md">Edit this page</a></div>
  <b>authors:</b> Jason Lowe-Power<br>
  

  <br>
  <h1 id="configuring-for-a-standard-protocol">Configuring for a standard protocol</h1>

<p>You can easily adapt the simple example configurations from this part to
the other SLICC protocols in gem5. In this chapter, we will briefly look
at an example with <code class="highlighter-rouge">MI_example</code>, though this can be easily extended to
other protocols.</p>

<p>However, these simple configuration files will only work in syscall
emulation mode. Full system mode adds some complications such as DMA
controllers. These scripts can be extended to full system.</p>

<p>For <code class="highlighter-rouge">MI_example</code>, we can use exactly the same runscript as before
(<code class="highlighter-rouge">simple_ruby.py</code>), we just need to implement a different
<code class="highlighter-rouge">MyCacheSystem</code> (and import that file in <code class="highlighter-rouge">simple_ruby.py</code>). Below, is
the classes needed for <code class="highlighter-rouge">MI_example</code>. There are only a couple of changes
from <code class="highlighter-rouge">MSI</code>, mostly due to different naming schemes. You can download the
file
<a href="/_pages/static/scripts/part3/configs/ruby_caches_MI_example.py">here</a>.</p>

<div class="language-python highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">MyCacheSystem</span><span class="p">(</span><span class="n">RubySystem</span><span class="p">):</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span>
        <span class="k">if</span> <span class="n">buildEnv</span><span class="p">[</span><span class="s">'PROTOCOL'</span><span class="p">]</span> <span class="o">!=</span> <span class="s">'MI_example'</span><span class="p">:</span>
            <span class="n">fatal</span><span class="p">(</span><span class="s">"This system assumes MI_example!"</span><span class="p">)</span>

        <span class="nb">super</span><span class="p">(</span><span class="n">MyCacheSystem</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>

    <span class="k">def</span> <span class="nf">setup</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">system</span><span class="p">,</span> <span class="n">cpus</span><span class="p">,</span> <span class="n">mem_ctrls</span><span class="p">):</span>
        <span class="s">"""Set up the Ruby cache subsystem. Note: This can't be done in the
           constructor because many of these items require a pointer to the
           ruby system (self). This causes infinite recursion in initialize()
           if we do this in the __init__.
        """</span>
        <span class="c1"># Ruby's global network.
</span>        <span class="bp">self</span><span class="o">.</span><span class="n">network</span> <span class="o">=</span> <span class="n">MyNetwork</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span>

        <span class="c1"># MI example uses 5 virtual networks
</span>        <span class="bp">self</span><span class="o">.</span><span class="n">number_of_virtual_networks</span> <span class="o">=</span> <span class="mi">5</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">network</span><span class="o">.</span><span class="n">number_of_virtual_networks</span> <span class="o">=</span> <span class="mi">5</span>

        <span class="c1"># There is a single global list of all of the controllers to make it
</span>        <span class="c1"># easier to connect everything to the global network. This can be
</span>        <span class="c1"># customized depending on the topology/network requirements.
</span>        <span class="c1"># Create one controller for each L1 cache (and the cache mem obj.)
</span>        <span class="c1"># Create a single directory controller (Really the memory cntrl)
</span>        <span class="bp">self</span><span class="o">.</span><span class="n">controllers</span> <span class="o">=</span> \
            <span class="p">[</span><span class="n">L1Cache</span><span class="p">(</span><span class="n">system</span><span class="p">,</span> <span class="bp">self</span><span class="p">,</span> <span class="n">cpu</span><span class="p">)</span> <span class="k">for</span> <span class="n">cpu</span> <span class="ow">in</span> <span class="n">cpus</span><span class="p">]</span> <span class="o">+</span> \
            <span class="p">[</span><span class="n">DirController</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">system</span><span class="o">.</span><span class="n">mem_ranges</span><span class="p">,</span> <span class="n">mem_ctrls</span><span class="p">)]</span>

        <span class="c1"># Create one sequencer per CPU. In many systems this is more
</span>        <span class="c1"># complicated since you have to create sequencers for DMA controllers
</span>        <span class="c1"># and other controllers, too.
</span>        <span class="bp">self</span><span class="o">.</span><span class="n">sequencers</span> <span class="o">=</span> <span class="p">[</span><span class="n">RubySequencer</span><span class="p">(</span><span class="n">version</span> <span class="o">=</span> <span class="n">i</span><span class="p">,</span>
                                <span class="c1"># I/D cache is combined and grab from ctrl
</span>                                <span class="n">icache</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">controllers</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">cacheMemory</span><span class="p">,</span>
                                <span class="n">dcache</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">controllers</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">cacheMemory</span><span class="p">,</span>
                                <span class="n">clk_domain</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">controllers</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">clk_domain</span><span class="p">,</span>
                                <span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">cpus</span><span class="p">))]</span>

        <span class="k">for</span> <span class="n">i</span><span class="p">,</span><span class="n">c</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">controllers</span><span class="p">[</span><span class="mi">0</span><span class="p">:</span><span class="nb">len</span><span class="p">(</span><span class="n">cpus</span><span class="p">)]):</span>
            <span class="n">c</span><span class="o">.</span><span class="n">sequencer</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sequencers</span><span class="p">[</span><span class="n">i</span><span class="p">]</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">num_of_sequencers</span> <span class="o">=</span> <span class="nb">len</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">sequencers</span><span class="p">)</span>

        <span class="c1"># Create the network and connect the controllers.
</span>        <span class="c1"># NOTE: This is quite different if using Garnet!
</span>        <span class="bp">self</span><span class="o">.</span><span class="n">network</span><span class="o">.</span><span class="n">connectControllers</span><span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">controllers</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">network</span><span class="o">.</span><span class="n">setup_buffers</span><span class="p">()</span>

        <span class="c1"># Set up a proxy port for the system_port. Used for load binaries and
</span>        <span class="c1"># other functional-only things.
</span>        <span class="bp">self</span><span class="o">.</span><span class="n">sys_port_proxy</span> <span class="o">=</span> <span class="n">RubyPortProxy</span><span class="p">()</span>
        <span class="n">system</span><span class="o">.</span><span class="n">system_port</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sys_port_proxy</span><span class="o">.</span><span class="n">slave</span>

        <span class="c1"># Connect the cpu's cache, interrupt, and TLB ports to Ruby
</span>        <span class="k">for</span> <span class="n">i</span><span class="p">,</span><span class="n">cpu</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">cpus</span><span class="p">):</span>
            <span class="n">cpu</span><span class="o">.</span><span class="n">icache_port</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sequencers</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">slave</span>
            <span class="n">cpu</span><span class="o">.</span><span class="n">dcache_port</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sequencers</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">slave</span>
            <span class="n">isa</span> <span class="o">=</span> <span class="n">buildEnv</span><span class="p">[</span><span class="s">'TARGET_ISA'</span><span class="p">]</span>
            <span class="k">if</span> <span class="n">isa</span> <span class="o">==</span> <span class="s">'x86'</span><span class="p">:</span>
                <span class="n">cpu</span><span class="o">.</span><span class="n">interrupts</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">pio</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sequencers</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">master</span>
                <span class="n">cpu</span><span class="o">.</span><span class="n">interrupts</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">int_master</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sequencers</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">slave</span>
                <span class="n">cpu</span><span class="o">.</span><span class="n">interrupts</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">int_slave</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sequencers</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">master</span>
            <span class="k">if</span> <span class="n">isa</span> <span class="o">==</span> <span class="s">'x86'</span> <span class="ow">or</span> <span class="n">isa</span> <span class="o">==</span> <span class="s">'arm'</span><span class="p">:</span>
                <span class="n">cpu</span><span class="o">.</span><span class="n">itb</span><span class="o">.</span><span class="n">walker</span><span class="o">.</span><span class="n">port</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sequencers</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">slave</span>
                <span class="n">cpu</span><span class="o">.</span><span class="n">dtb</span><span class="o">.</span><span class="n">walker</span><span class="o">.</span><span class="n">port</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sequencers</span><span class="p">[</span><span class="n">i</span><span class="p">]</span><span class="o">.</span><span class="n">slave</span>

<span class="k">class</span> <span class="nc">L1Cache</span><span class="p">(</span><span class="n">L1Cache_Controller</span><span class="p">):</span>

    <span class="n">_version</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="o">@</span><span class="nb">classmethod</span>
    <span class="k">def</span> <span class="nf">versionCount</span><span class="p">(</span><span class="n">cls</span><span class="p">):</span>
        <span class="n">cls</span><span class="o">.</span><span class="n">_version</span> <span class="o">+=</span> <span class="mi">1</span> <span class="c1"># Use count for this particular type
</span>        <span class="k">return</span> <span class="n">cls</span><span class="o">.</span><span class="n">_version</span> <span class="o">-</span> <span class="mi">1</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">system</span><span class="p">,</span> <span class="n">ruby_system</span><span class="p">,</span> <span class="n">cpu</span><span class="p">):</span>
        <span class="s">"""CPUs are needed to grab the clock domain and system is needed for
           the cache block size.
        """</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">L1Cache</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">version</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">versionCount</span><span class="p">()</span>
        <span class="c1"># This is the cache memory object that stores the cache data and tags
</span>        <span class="bp">self</span><span class="o">.</span><span class="n">cacheMemory</span> <span class="o">=</span> <span class="n">RubyCache</span><span class="p">(</span><span class="n">size</span> <span class="o">=</span> <span class="s">'16kB'</span><span class="p">,</span>
                               <span class="n">assoc</span> <span class="o">=</span> <span class="mi">8</span><span class="p">,</span>
                               <span class="n">start_index_bit</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">getBlockSizeBits</span><span class="p">(</span><span class="n">system</span><span class="p">))</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">clk_domain</span> <span class="o">=</span> <span class="n">cpu</span><span class="o">.</span><span class="n">clk_domain</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">send_evictions</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">sendEvicts</span><span class="p">(</span><span class="n">cpu</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">ruby_system</span> <span class="o">=</span> <span class="n">ruby_system</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">connectQueues</span><span class="p">(</span><span class="n">ruby_system</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">getBlockSizeBits</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">system</span><span class="p">):</span>
        <span class="n">bits</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">math</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="n">system</span><span class="o">.</span><span class="n">cache_line_size</span><span class="p">,</span> <span class="mi">2</span><span class="p">))</span>
        <span class="k">if</span> <span class="mi">2</span><span class="o">**</span><span class="n">bits</span> <span class="o">!=</span> <span class="n">system</span><span class="o">.</span><span class="n">cache_line_size</span><span class="o">.</span><span class="n">value</span><span class="p">:</span>
            <span class="n">panic</span><span class="p">(</span><span class="s">"Cache line size not a power of 2!"</span><span class="p">)</span>
        <span class="k">return</span> <span class="n">bits</span>

    <span class="k">def</span> <span class="nf">sendEvicts</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">cpu</span><span class="p">):</span>
        <span class="s">"""True if the CPU model or ISA requires sending evictions from caches
           to the CPU. Two scenarios warrant forwarding evictions to the CPU:
           1. The O3 model must keep the LSQ coherent with the caches
           2. The x86 mwait instruction is built on top of coherence
           3. The local exclusive monitor in ARM systems
        """</span>
        <span class="k">if</span> <span class="nb">type</span><span class="p">(</span><span class="n">cpu</span><span class="p">)</span> <span class="ow">is</span> <span class="n">DerivO3CPU</span> <span class="ow">or</span> \
           <span class="n">buildEnv</span><span class="p">[</span><span class="s">'TARGET_ISA'</span><span class="p">]</span> <span class="ow">in</span> <span class="p">(</span><span class="s">'x86'</span><span class="p">,</span> <span class="s">'arm'</span><span class="p">):</span>
            <span class="k">return</span> <span class="bp">True</span>
        <span class="k">return</span> <span class="bp">False</span>

    <span class="k">def</span> <span class="nf">connectQueues</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ruby_system</span><span class="p">):</span>
        <span class="s">"""Connect all of the queues for this controller.
        """</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">mandatoryQueue</span> <span class="o">=</span> <span class="n">MessageBuffer</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">requestFromCache</span> <span class="o">=</span> <span class="n">MessageBuffer</span><span class="p">(</span><span class="n">ordered</span> <span class="o">=</span> <span class="bp">True</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">requestFromCache</span><span class="o">.</span><span class="n">master</span> <span class="o">=</span> <span class="n">ruby_system</span><span class="o">.</span><span class="n">network</span><span class="o">.</span><span class="n">slave</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">responseFromCache</span> <span class="o">=</span> <span class="n">MessageBuffer</span><span class="p">(</span><span class="n">ordered</span> <span class="o">=</span> <span class="bp">True</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">responseFromCache</span><span class="o">.</span><span class="n">master</span> <span class="o">=</span> <span class="n">ruby_system</span><span class="o">.</span><span class="n">network</span><span class="o">.</span><span class="n">slave</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">forwardToCache</span> <span class="o">=</span> <span class="n">MessageBuffer</span><span class="p">(</span><span class="n">ordered</span> <span class="o">=</span> <span class="bp">True</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">forwardToCache</span><span class="o">.</span><span class="n">slave</span> <span class="o">=</span> <span class="n">ruby_system</span><span class="o">.</span><span class="n">network</span><span class="o">.</span><span class="n">master</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">responseToCache</span> <span class="o">=</span> <span class="n">MessageBuffer</span><span class="p">(</span><span class="n">ordered</span> <span class="o">=</span> <span class="bp">True</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">responseToCache</span><span class="o">.</span><span class="n">slave</span> <span class="o">=</span> <span class="n">ruby_system</span><span class="o">.</span><span class="n">network</span><span class="o">.</span><span class="n">master</span>

<span class="k">class</span> <span class="nc">DirController</span><span class="p">(</span><span class="n">Directory_Controller</span><span class="p">):</span>

    <span class="n">_version</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="o">@</span><span class="nb">classmethod</span>
    <span class="k">def</span> <span class="nf">versionCount</span><span class="p">(</span><span class="n">cls</span><span class="p">):</span>
        <span class="n">cls</span><span class="o">.</span><span class="n">_version</span> <span class="o">+=</span> <span class="mi">1</span> <span class="c1"># Use count for this particular type
</span>        <span class="k">return</span> <span class="n">cls</span><span class="o">.</span><span class="n">_version</span> <span class="o">-</span> <span class="mi">1</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ruby_system</span><span class="p">,</span> <span class="n">ranges</span><span class="p">,</span> <span class="n">mem_ctrls</span><span class="p">):</span>
        <span class="s">"""ranges are the memory ranges assigned to this controller.
        """</span>
        <span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">mem_ctrls</span><span class="p">)</span> <span class="o">&gt;</span> <span class="mi">1</span><span class="p">:</span>
            <span class="n">panic</span><span class="p">(</span><span class="s">"This cache system can only be connected to one mem ctrl"</span><span class="p">)</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">DirController</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">version</span> <span class="o">=</span> <span class="bp">self</span><span class="o">.</span><span class="n">versionCount</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">addr_ranges</span> <span class="o">=</span> <span class="n">ranges</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">ruby_system</span> <span class="o">=</span> <span class="n">ruby_system</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">directory</span> <span class="o">=</span> <span class="n">RubyDirectoryMemory</span><span class="p">()</span>
        <span class="c1"># Connect this directory to the memory side.
</span>        <span class="bp">self</span><span class="o">.</span><span class="n">memory</span> <span class="o">=</span> <span class="n">mem_ctrls</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span><span class="o">.</span><span class="n">port</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">connectQueues</span><span class="p">(</span><span class="n">ruby_system</span><span class="p">)</span>

    <span class="k">def</span> <span class="nf">connectQueues</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ruby_system</span><span class="p">):</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">requestToDir</span> <span class="o">=</span> <span class="n">MessageBuffer</span><span class="p">(</span><span class="n">ordered</span> <span class="o">=</span> <span class="bp">True</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">requestToDir</span><span class="o">.</span><span class="n">slave</span> <span class="o">=</span> <span class="n">ruby_system</span><span class="o">.</span><span class="n">network</span><span class="o">.</span><span class="n">master</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">dmaRequestToDir</span> <span class="o">=</span> <span class="n">MessageBuffer</span><span class="p">(</span><span class="n">ordered</span> <span class="o">=</span> <span class="bp">True</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">dmaRequestToDir</span><span class="o">.</span><span class="n">slave</span> <span class="o">=</span> <span class="n">ruby_system</span><span class="o">.</span><span class="n">network</span><span class="o">.</span><span class="n">master</span>

        <span class="bp">self</span><span class="o">.</span><span class="n">responseFromDir</span> <span class="o">=</span> <span class="n">MessageBuffer</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">responseFromDir</span><span class="o">.</span><span class="n">master</span> <span class="o">=</span> <span class="n">ruby_system</span><span class="o">.</span><span class="n">network</span><span class="o">.</span><span class="n">slave</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">dmaResponseFromDir</span> <span class="o">=</span> <span class="n">MessageBuffer</span><span class="p">(</span><span class="n">ordered</span> <span class="o">=</span> <span class="bp">True</span><span class="p">)</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">dmaResponseFromDir</span><span class="o">.</span><span class="n">master</span> <span class="o">=</span> <span class="n">ruby_system</span><span class="o">.</span><span class="n">network</span><span class="o">.</span><span class="n">slave</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">forwardFromDir</span> <span class="o">=</span> <span class="n">MessageBuffer</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">forwardFromDir</span><span class="o">.</span><span class="n">master</span> <span class="o">=</span> <span class="n">ruby_system</span><span class="o">.</span><span class="n">network</span><span class="o">.</span><span class="n">slave</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">responseFromMemory</span> <span class="o">=</span> <span class="n">MessageBuffer</span><span class="p">()</span>

<span class="k">class</span> <span class="nc">MyNetwork</span><span class="p">(</span><span class="n">SimpleNetwork</span><span class="p">):</span>
    <span class="s">"""A simple point-to-point network. This doesn't not use garnet.
    """</span>

    <span class="k">def</span> <span class="nf">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">ruby_system</span><span class="p">):</span>
        <span class="nb">super</span><span class="p">(</span><span class="n">MyNetwork</span><span class="p">,</span> <span class="bp">self</span><span class="p">)</span><span class="o">.</span><span class="n">__init__</span><span class="p">()</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">netifs</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">ruby_system</span> <span class="o">=</span> <span class="n">ruby_system</span>

    <span class="k">def</span> <span class="nf">connectControllers</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">controllers</span><span class="p">):</span>
        <span class="s">"""Connect all of the controllers to routers and connect the routers
           together in a point-to-point network.
        """</span>
        <span class="c1"># Create one router/switch per controller in the system
</span>        <span class="bp">self</span><span class="o">.</span><span class="n">routers</span> <span class="o">=</span> <span class="p">[</span><span class="n">Switch</span><span class="p">(</span><span class="n">router_id</span> <span class="o">=</span> <span class="n">i</span><span class="p">)</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">controllers</span><span class="p">))]</span>

        <span class="c1"># Make a link from each controller to the router. The link goes
</span>        <span class="c1"># externally to the network.
</span>        <span class="bp">self</span><span class="o">.</span><span class="n">ext_links</span> <span class="o">=</span> <span class="p">[</span><span class="n">SimpleExtLink</span><span class="p">(</span><span class="n">link_id</span><span class="o">=</span><span class="n">i</span><span class="p">,</span> <span class="n">ext_node</span><span class="o">=</span><span class="n">c</span><span class="p">,</span>
                                        <span class="n">int_node</span><span class="o">=</span><span class="bp">self</span><span class="o">.</span><span class="n">routers</span><span class="p">[</span><span class="n">i</span><span class="p">])</span>
                          <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">c</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">controllers</span><span class="p">)]</span>

        <span class="c1"># Make an "internal" link (internal to the network) between every pair
</span>        <span class="c1"># of routers.
</span>        <span class="n">link_count</span> <span class="o">=</span> <span class="mi">0</span>
        <span class="bp">self</span><span class="o">.</span><span class="n">int_links</span> <span class="o">=</span> <span class="p">[]</span>
        <span class="k">for</span> <span class="n">ri</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">routers</span><span class="p">:</span>
            <span class="k">for</span> <span class="n">rj</span> <span class="ow">in</span> <span class="bp">self</span><span class="o">.</span><span class="n">routers</span><span class="p">:</span>
                <span class="k">if</span> <span class="n">ri</span> <span class="o">==</span> <span class="n">rj</span><span class="p">:</span> <span class="k">continue</span> <span class="c1"># Don't connect a router to itself!
</span>                <span class="n">link_count</span> <span class="o">+=</span> <span class="mi">1</span>
                <span class="bp">self</span><span class="o">.</span><span class="n">int_links</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">SimpleIntLink</span><span class="p">(</span><span class="n">link_id</span> <span class="o">=</span> <span class="n">link_count</span><span class="p">,</span>
                                                    <span class="n">src_node</span> <span class="o">=</span> <span class="n">ri</span><span class="p">,</span>
                                                    <span class="n">dst_node</span> <span class="o">=</span> <span class="n">rj</span><span class="p">))</span>
</code></pre></div></div>

  <br>

  <!-- RETRIVE PREVIOUS PAGE LINK -->
  
    
  
    
  
    
  
    
  

  <!-- RETRIEVE NEXT PAGE LINK -->
  
    
  
    
  
    
  
    
  


  <div class="navbuttons">
    
      <a href=""><button type="button" class="btn btn-outline-primary">PREVIOUS</button></a>
    

    
      <a href=""><button type="button" class="btn btn-outline-primary">NEXT</button></a>
    
  </div>
</div>

	</main>
	<footer class="page-footer">
	<div class="container">
		<div class="row">

			<div class="col-12 col-sm-4">
				<p>gem5</p>
				<p><a href="/about">About</a></p>
				<p><a href="/publications">Publications</a></p>
				<p><a href="/contributing">Contributing</a></p>
				<p><a href="/governance">Governance</a></p>
			<br></div>

			<div class="col-12 col-sm-4">
				<p>Docs</p>
				<p><a href="/documentation">Documentation</a></p>
				<p><a href="http://gem5.org/Documentation">Old Documentation</a></p>
				<p><a href="https://gem5.googlesource.com/public/gem5">Source</a></p>
			<br></div>

			<div class="col-12 col-sm-4">
				<p>Help</p>
				<p><a href="/search">Search</a></p>
				<p><a href="/mailing_lists">Mailing Lists</a></p>
				<p><a href="https://gem5.googlesource.com/public/gem5-website/+/refs/heads/master/README.md">Website Source</a></p>
			<br></div>

		</div>
	</div>
</footer>


	<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script>
	<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.3/umd/popper.min.js" integrity="sha384-ZMP7rVo3mIykV+2+9J3UJ46jBk0WLaUAdn689aCwoqbBJiSnjAK/l8WvCWPIPm49" crossorigin="anonymous"></script>
	<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/js/bootstrap.min.js" integrity="sha384-ChfqqxuZUCnJSK3+MXmPNIyE6ZbWh2IMqE241rYiqJxyMiZ6OW/JmZQ5stwEULTy" crossorigin="anonymous"></script>
	<script src="https://unpkg.com/commentbox.io/dist/commentBox.min.js"></script>

	<script>
	  // When the user scrolls down 20px from the top of the document, show the button
	  window.onscroll = function() {scrollFunction()};

	  function scrollFunction() {
	      if (document.body.scrollTop > 100 || document.documentElement.scrollTop > 20) {
	          document.getElementById("myBtn").style.display = "block";
	      } else {
	          document.getElementById("myBtn").style.display = "none";
	      }
	  }

	  // When the user clicks on the button, scroll to the top of the document
	  function topFunction() {
	      document.body.scrollTop = 0;
	      document.documentElement.scrollTop = 0;
	  }

		import commentBox from 'commentbox.io';
		// or
		const commentBox = require('commentbox.io');
		// or if using the CDN, it will be available as a global "commentBox" variable.

		commentBox('my-project-id');

	</script>

</body>


</html>
